// http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
"use strict";

// Optional. You will see this name in eg. 'ps' or 'top' command
process.title = 'node-chat';

//Port where we'll run the websocket server****
var webSocketsServerPort = 1337;

// websocket and http servers***
var webSocketServer = require('websocket').server;
var http = require('http');
var requirejs = require('requirejs');
console.log('loaded requirejs...');
requirejs(['blasteroids/ship', 'blasteroids/gamestate'], function (Ship, GameState) {
    console.log('loaded blasteroids/ship & blasteroids/gamestate...');
    //Global variables***
    // list of currently connected clients (users)
    var clients = new Array();
    var gameState = new GameState();
    var sendGameStateInterval = 1000;
    var updateGameStateInterval = 1;

    //HTTP server***
    var server = http.createServer(function(request, response) {
        //Not important for us. We're writing WebSocket server, not HTTP server
        });
    server.listen(webSocketsServerPort, function() {
        console.log((new Date()) + " Server is listening on port " + webSocketsServerPort);
    });

    //WebSocket server****
    var wsServer = new webSocketServer({
        // WebSocket server is tied to a HTTP server. WebSocket request is just
        // an enhanced HTTP request. For more info http://tools.ietf.org/html/rfc6455#page-6
        httpServer: server
    });

    // This callback function is called every time someone
    // tries to connect to the WebSocket server
    wsServer.on('request', function(request) {
	
        //accept the connection
        var connection = request.accept(null, request.origin);
    
        //add him to our list of clients
        clients.push(connection);
    
        //globals for this user:
        var ship = null;
        var then = new Date(); // we'll use this for the modifier in the update function
        var started = false; //whether the player has joined.
    
        connection.on('message', function(message) {
            var packet = JSON.parse(message.utf8Data);
            //console.log('recieved message: ' + JSON.stringify(packet));
            if(packet.type=='action'){
                if(started){
                    //take in the action, apply it, and then send it to everyone
                    gameState.processAction(packet.data);
                    emit({
                        type:'action',
                        data:packet.data
                    }, connection);
                }
            }else if(packet.type=='joinGame'){
                console.log('recieved join game, data: ' + JSON.stringify(packet.data));
                ship = new Ship(packet.data.name, 0, gameState.canvasSize, packet.data.color, packet.data.image);
                if(gameState.addShip(ship)){
                    //emit it to everyone
                    started = true;
                    emit(packet, connection);
                }else{
                    connection.send(JSON.stringify({
                        type:'error',
                        data:'Name already in use, pick another'
                    }));
                }
            }
        });
        connection.onclose = function (error) {
            alert('Connection from user:'+ship.name+' closed');
        };
        
    });

    var emit= function(message, connection){
        message = JSON.stringify(message);
        var length = clients.length;
        if(length > 0){
        //console.log('emitting message to '+length+' clients: '+ message);
        }
        for(var i=0; i<length; i++){
            if(clients[i] != connection){
                clients[i].send(message);
            }
        }
    };

    var then = new Date();
    var update = function(){
        var now = new Date();
        var modifier = ((now-then)/1000);
        gameState.update(modifier);
        then = now;
    }
    
    setInterval(update, updateGameStateInterval);
    setInterval(function(){
        emit({
            type:'gameState',
            data:gameState.getInfo()
        });
    }, sendGameStateInterval);

});